// #include <iostream>
// #include <string>
// #include <functional>
// #include <stdlib.h>
// #include <vector>
// #include <unordered_map>
// #include <ctime>
// #include <sys/types.h>
// #include <sys/wait.h>

// // 进程头文件
// #include <unistd.h>

// using work_t = std::function<void()>; // 返回值是void 参数为空
// static int num;                       // 计数器 编号

// //>>>>>状态栏编号
// enum
// {
//     OK,
//     UsageRrror,
//     PipeError,
//     ForkError
// };

// //>>>>>>任务
// //>>>任务（1）
// void Print_hw()
// {
//     std::cout << "hello world！,pid:" << getpid() << std::endl;
// }
// //>>>任务（2）
// void Print_nm()
// {

//     std::cout << "my name is pid:" << getpid() << std::endl;
// }

// void Print_love()
// {
//     std::cout << "I love 尹心怡" << getpid() << std::endl;
// }

// //>>>>>任务管理
// class Task
// {
// public:
//     // 初始化任务
//     Task()
//     {
//         srand((unsigned)time(NULL));
//         Insert(Print_hw);
//         Insert(Print_nm);
//         Insert(Print_love);
//     }
//     // 插入任务
//     void Insert(work_t t)
//     {
//         tasks[num++] = t;
//     }
//     // 选择任务 随机
//     int Select()
//     {
//         unsigned _n = rand() % num;
//         return _n;
//     }
//     // 销毁任务
//     ~Task()
//     {
//     }
//     // 执行对应的方法
//     void Excute(int number)
//     {
//         if (tasks.find(number) == tasks.end())
//             return;      // 没找到什么都不做
//         tasks[number](); // 执行这个程序
//     }

// private:
//     std::unordered_map<int, work_t> tasks;
// };
// Task _tm;

// //>>>>>管道特点
// class Channel
// {
// public:
//     // 管道 初始化 前面是管道写端的文件描述符 后面是子进程id
//     Channel(int fd, int pid) : _fd(fd), _who(pid)
//     {
//         _name = "Channel-" + std::to_string(_fd) + "-" + std::to_string(_who);
//     }

//     // 管道的销毁
//     // ~Channel()
//     // {
//     // }

//     std::string Name()
//     {
//         return _name;
//     }

//     // 用管道派发任务
//     void Send(int _cmd) //_cmd 就是任务码
//     {
//         ::write(_fd, &_cmd, sizeof(_cmd)); // 把任务码发送到写端
//     }

//     // 关闭管道的方法
//     void Close()
//     {
//         ::close(_fd);
//     }
//     pid_t Id()
//     {
//         return _who;
//     }

// private:
//     int _fd;    // 父进程 管道的写端
//     pid_t _who; // 子进程的id
//     std::string _name = "";
// };

// //>>>>>子进程接收到信息后 Send()完毕之后 开始工作
// void Work()
// {
//     // 1:50:00

//     while (true)
//     {
//         int _cmd = 0;
//         int n = ::read(0, &_cmd, sizeof(_cmd)); // 因为dup2 重定向了
//         if (n == sizeof(int))                   // 如果正好 在标准输入里面读取到一个字节 其实就是管道读到了 因为重定向了
//         {
//             _tm.Excute(_cmd);
//         }
//         else if (n == 0)
//         {
//             std::cout << "pid:" << getpid() << "quit..." << std::endl;
//             break; // 这就会直接跳出循环 下面有个exit就会退出
//         }
//         else
//         {
//         }
//     }
// }

// //>>>>>加载进程
// int progressAll(const int &_num, std::vector<Channel> &_channels, work_t work)
// {
//     for (int i = 0; i < _num; i++)
//     {
//         // 创建管道
//         int pipeArr[2] = {0};
//         int _flag1 = pipe(pipeArr);
//         if (_flag1 < 0)
//         {
//             return PipeError; // 表示管道创建失败了
//         }

//         // 管道创建成功
//         // 创建进程
//         pid_t id = fork(); // 会继承 父进程的 C hannel
//         if (id < 0)
//             return ForkError; // 进程创建失败
//         if (id == 0)          // 说明进程 创建成功
//         {
//             ::close(pipeArr[1]); // 子进程关闭 写
//             dup2(pipeArr[0], 0); // 重定向到
//             work();
//             ::exit(0);
//         }
//         ::close(pipeArr[0]); // 父进程 关闭读进程
//         _channels.emplace_back(pipeArr[1], id);
//     }
//     return 0;
// }

// //>>>>>指令输入纠正
// void Usage(std::string _s)
// {
//     std::cout << "_s" << "使用方式不对" << std::endl;
// }

// //>>>>>派发任务
// void DispatchTask(std::vector<Channel> &_allchannel)
// {
//     int who = 0;
//     int _num = 5;
//     while (_num--)
//     {
//         // a.选择一个任务，整数
//         int _task = _tm.Select(); //_task 用来存 任务码

//         // b.选择一个子进程的管道channel
//         Channel &_channel = _allchannel[who++];

//         who %= _allchannel.size();
//         std::cout << "###################" << std::endl;

//         // c.派发任务
//         _channel.Send(_task); // 把任务派发给子进程的管道
//         sleep(2);
//     }
// }

// //>>>>>清理进程池
// void CleanProcessPool(std::vector<Channel> &_allchannel)
// {
//     for (auto &_a : _allchannel)
//     {
//         _a.Close();
//     }
//     for (auto &_a : _allchannel)
//     {

//         pid_t _waitid = waitpid(_a.Id(), nullptr, 0);
//         if (_waitid > 0)
//         {
//             std::cout << "child" << _waitid << "wait ... success" << std::endl;
//         }
//     }
// }

// //>>>>>主函数
// int main(int argc, char *argv[])
// {

//     // 首先输入指令
//     if (argc > 2)
//     {
//         Usage(argv[0]);
//         return UsageRrror;
//     }
//     int _num = std::stoi(argv[1]);
//     std::vector<Channel> _allchannel; // 这个用来存放所有的管道

//     // 1.输出进程池
//     progressAll(_num, _allchannel, Work);

//     // 2.派发任务
//     DispatchTask(_allchannel);

//     // 3.退出进程池
//     CleanProcessPool(_allchannel);

//     return 0;
// }
